bitkeeper revision 1.825.5.1 (40644991zRxZVjAd23Dlw69CHQg32A)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Fri, 26 Mar 2004 15:17:37 +0000 (15:17 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Fri, 26 Mar 2004 15:17:37 +0000 (15:17 +0000)
irq.h, interrupt.h, console.c, physdev.c, event_channel.c, irq.c, io_apic.c:
  More support in Xen for binding IRQs to guests. Also changed console redirect sequence to triple-ctrl-g -- ctrl-a is a useful editing command.

xen/arch/i386/io_apic.c
xen/arch/i386/irq.c
xen/common/event_channel.c
xen/common/physdev.c
xen/drivers/char/console.c
xen/include/asm-i386/irq.h
xen/include/asm-x86_64/irq.h
xen/include/xen/interrupt.h
xen/include/xen/irq.h

index c4a2e4853549bd889d15e77fe6e8d311010d69f2..96c8b9a54e088402a12ef57fce72fe7e4156da8c 100644 (file)
@@ -138,14 +138,10 @@ static void __init replace_pin_at_irq(unsigned int irq,
        static void name##_IO_APIC_irq (unsigned int irq)               \
        __DO_ACTION(R, ACTION, FINAL)
 
-DO_ACTION( __mask,             0, |= 0x00010000, io_apic_sync(entry->apic) )
-                                               /* mask = 1 */
-DO_ACTION( __unmask,           0, &= 0xfffeffff, )
-                                               /* mask = 0 */
-DO_ACTION( __mask_and_edge,    0, = (reg & 0xffff7fff) | 0x00010000, )
-                                               /* mask = 1, trigger = 0 */
-DO_ACTION( __unmask_and_level, 0, = (reg & 0xfffeffff) | 0x00008000, )
-                                               /* mask = 0, trigger = 1 */
+DO_ACTION( __mask,    0, |= 0x00010000, io_apic_sync(entry->apic) )
+DO_ACTION( __unmask,  0, &= 0xfffeffff, )
+DO_ACTION( __edge,    0, &= 0xffff7fff, )
+DO_ACTION( __level,   0, |= 0x00008000, )
 
 static void mask_IO_APIC_irq (unsigned int irq)
 {
@@ -1365,13 +1361,15 @@ static unsigned int startup_level_ioapic_irq (unsigned int irq)
        return 0; /* don't check for pending */
 }
 
-static void end_level_ioapic_irq (unsigned int irq)
+static void mask_and_ack_level_ioapic_irq(unsigned int irq)
 {
        unsigned long v;
        int i;
 
        balance_irq(irq);
 
+       mask_IO_APIC_irq(irq);
+
 /*
  * It appears there is an erratum which affects at least version 0x11
  * of I/O APIC (that's the 82093AA and cores integrated into various
@@ -1405,7 +1403,7 @@ static void end_level_ioapic_irq (unsigned int irq)
                atomic_inc(&irq_mis_count);
 #endif
                spin_lock(&ioapic_lock);
-               __mask_and_edge_IO_APIC_irq(irq);
+               __edge_IO_APIC_irq(irq);
 #ifdef APIC_LOCKUP_DEBUG
                for (entry = irq_2_pin + irq;;) {
                        unsigned int reg;
@@ -1421,12 +1419,15 @@ static void end_level_ioapic_irq (unsigned int irq)
                        entry = irq_2_pin + entry->next;
                }
 #endif
-               __unmask_and_level_IO_APIC_irq(irq);
+               __level_IO_APIC_irq(irq);
                spin_unlock(&ioapic_lock);
        }
 }
 
-static void mask_and_ack_level_ioapic_irq (unsigned int irq) { /* nothing */ }
+static void end_level_ioapic_irq(unsigned int irq)
+{
+       unmask_IO_APIC_irq(irq);
+}
 
 static inline void init_IO_APIC_traps(void)
 {
index 6b45b02080cf8d9c5f8d04476e343d4deef4cd72..19cf5c7dc486490076dc7ec25cf7e854f002276d 100644 (file)
@@ -24,6 +24,7 @@
 #include <xen/interrupt.h>
 #include <xen/irq.h>
 #include <xen/slab.h>
+#include <xen/event.h>
 #include <asm/mpspec.h>
 #include <asm/io_apic.h>
 #include <asm/msr.h>
@@ -66,6 +67,8 @@ irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
 unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
 #endif
 
+static void __do_IRQ_guest(int irq);
+
 /*
  * Special irq handlers.
  */
@@ -333,7 +336,9 @@ void __global_restore_flags(unsigned long flags)
  * waste of time and is not what some drivers would
  * prefer.
  */
-int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action)
+static int handle_IRQ_event(unsigned int irq, 
+                            struct pt_regs * regs, 
+                            struct irqaction * action)
 {
     int status;
     int cpu = smp_processor_id();
@@ -483,6 +488,7 @@ asmlinkage unsigned int do_IRQ(struct pt_regs regs)
 
     spin_lock(&desc->lock);
     desc->handler->ack(irq);
+
     /*
       REPLAY is when Linux resends an IRQ that was dropped earlier
       WAITING is used by probe to mark irqs that are being tested
@@ -490,6 +496,14 @@ asmlinkage unsigned int do_IRQ(struct pt_regs regs)
     status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
     status |= IRQ_PENDING; /* we _want_ to handle it */
 
+    /* We hook off guest-bound IRQs for special handling. */
+    if ( status & IRQ_GUEST )
+    {
+        __do_IRQ_guest(irq);
+        spin_unlock(&desc->lock);
+        return 1;
+    }
+
     /*
      * If the IRQ is disabled for whatever reason, we cannot use the action we 
      * have.
@@ -883,6 +897,13 @@ int setup_irq(unsigned int irq, struct irqaction * new)
      * The following block of code has to be executed atomically
      */
     spin_lock_irqsave(&desc->lock,flags);
+
+    if ( desc->status & IRQ_GUEST )
+    {
+        spin_unlock_irqrestore(&desc->lock,flags);
+        return -EBUSY;
+    }
+
     p = &desc->action;
     if ((old = *p) != NULL) {
         /* Can't share interrupts unless both agree to */
@@ -906,7 +927,110 @@ int setup_irq(unsigned int irq, struct irqaction * new)
         desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING);
         desc->handler->startup(irq);
     }
+
     spin_unlock_irqrestore(&desc->lock,flags);
 
     return 0;
 }
+
+
+
+/*
+ * HANDLING OF GUEST-BOUND PHYSICAL IRQS
+ */
+
+#define IRQ_MAX_GUESTS 7
+typedef struct {
+    unsigned int nr_guests;
+    struct task_struct *guest[IRQ_MAX_GUESTS];
+} irq_guest_action_t;
+
+static void __do_IRQ_guest(int irq)
+{
+    irq_desc_t *desc = &irq_desc[irq];
+    irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
+    struct task_struct *p;
+    int i;
+
+    for ( i = 0; i < action->nr_guests; i++ )
+    {
+        p = action->guest[i];
+        send_guest_pirq(p, irq);
+    }
+}
+
+int pirq_guest_bind(struct task_struct *p, int irq)
+{
+    unsigned long flags;
+    irq_desc_t *desc = &irq_desc[irq];
+    irq_guest_action_t *action;
+    int rc;
+
+    if ( !IS_PRIV(p) )
+        return -EPERM;
+
+    spin_lock_irqsave(&desc->lock, flags);
+
+    if ( !(desc->status & IRQ_GUEST) )
+    {
+        rc = -EBUSY;
+        if ( desc->action != NULL )
+            goto out;
+
+        rc = -ENOMEM;
+        action = kmalloc(sizeof(irq_guest_action_t), GFP_KERNEL);
+        if ( (desc->action = (struct irqaction *)action) == NULL )
+            goto out;
+
+        action->nr_guests = 0;
+
+        desc->depth = 0;
+        desc->status |= IRQ_GUEST;
+        desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING);
+        desc->handler->startup(irq);
+    }
+
+    action = (irq_guest_action_t *)desc->action;
+
+    rc = -EBUSY;
+    if ( action->nr_guests == IRQ_MAX_GUESTS )
+        goto out;
+
+    action->guest[action->nr_guests++] = p;
+
+ out:
+    spin_unlock_irqrestore(&desc->lock, flags);
+    return rc;
+}
+
+int pirq_guest_unbind(struct task_struct *p, int irq)
+{
+    unsigned long flags;
+    irq_desc_t *desc = &irq_desc[irq];
+    irq_guest_action_t *action;
+    int i;
+
+    spin_lock_irqsave(&desc->lock, flags);
+
+    action = (irq_guest_action_t *)desc->action;
+
+    if ( action->nr_guests == 1 )
+    {
+        desc->action = NULL;
+        kfree(action);
+        desc->status |= IRQ_DISABLED;
+        desc->status &= ~IRQ_GUEST;
+        desc->handler->shutdown(irq);
+    }
+    else
+    {
+        i = 0;
+        while ( action->guest[i] != p )
+            i++;
+        memmove(&action->guest[i], &action->guest[i+1], IRQ_MAX_GUESTS-i-1);
+        action->nr_guests--;
+    }
+
+    spin_unlock_irqrestore(&desc->lock, flags);    
+    return 0;
+}
index d0c0f5bba0042ae5e916d5aadb60fa07fea84cfd..d68e28b5537f59885fdbac7ca0679e177c5878e6 100644 (file)
@@ -21,6 +21,7 @@
 #include <xen/errno.h>
 #include <xen/sched.h>
 #include <xen/event.h>
+#include <xen/irq.h>
 
 #include <hypervisor-ifs/hypervisor-if.h>
 #include <hypervisor-ifs/event_channel.h>
@@ -181,27 +182,32 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
 {
     struct task_struct *p = current;
     int pirq = bind->pirq;
-    int port;
+    int port, rc;
 
     if ( pirq >= ARRAY_SIZE(p->pirq_to_evtchn) )
         return -EINVAL;
 
     spin_lock(&p->event_channel_lock);
 
-    if ( ((port = p->pirq_to_evtchn[pirq]) != 0) ||
-         ((port = get_free_port(p)) < 0) )
+    if ( ((rc = port = p->pirq_to_evtchn[pirq]) != 0) ||
+         ((rc = port = get_free_port(p)) < 0) )
         goto out;
 
+    p->pirq_to_evtchn[pirq] = port;
+    if ( (rc = pirq_guest_bind(p, pirq)) != 0 )
+    {
+        p->pirq_to_evtchn[pirq] = 0;
+        goto out;
+    }
+
     p->event_channel[port].state  = ECS_PIRQ;
     p->event_channel[port].u.pirq = pirq;
 
-    p->pirq_to_evtchn[pirq] = port;
-
  out:
     spin_unlock(&p->event_channel_lock);
 
-    if ( port < 0 )
-        return port;
+    if ( rc < 0 )
+        return rc;
 
     bind->port = port;
     return 0;
@@ -237,7 +243,8 @@ static long __evtchn_close(struct task_struct *p1, int port1)
         break;
 
     case ECS_PIRQ:
-        p1->pirq_to_evtchn[chn1[port1].u.pirq] = 0;
+        if ( (rc = pirq_guest_unbind(p1, chn1[port1].u.pirq)) == 0 )
+            p1->pirq_to_evtchn[chn1[port1].u.pirq] = 0;
         break;
 
     case ECS_VIRQ:
index 08da1b5206895b62968872c537d46d2171215050..cc2f21b172883e92e38bf8bd8dac0679d61d6092 100644 (file)
 /* bit offsets into state */
 #define ST_BASE_ADDRESS  0   /* bits 0-5: are for base address access */
 #define ST_ROM_ADDRESS   6   /* bit 6: is for rom address access */    
-#define ST_IRQ_DELIVERED 7   /* bit 7: waiting for end irq call */    
 
-typedef struct _phys_dev_st
-{
+typedef struct _phys_dev_st {
     int flags;                       /* flags for access etc */
     struct pci_dev *dev;             /* the device */
     struct list_head node;           /* link to the list */
     struct task_struct *owner;       /* 'owner of this device' */
     int state;                       /* state for various checks */
-
-    hw_irq_controller *new_handler;  /* saved old handler */
-    hw_irq_controller *orig_handler; /* saved old handler */
-
 } phys_dev_t;
 
 
-#define MAX_IRQS 32
-/* an array of device descriptors index by IRQ number */
-static phys_dev_t *irqs[MAX_IRQS];
-
 /*
  * 
  * General functions
@@ -573,158 +563,9 @@ static long pci_find_irq(int seg, int bus, int dev, int func, u32 *val)
     return 0;
 }
 
-static void phys_dev_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
-{
-    phys_dev_t          *pdev;
-
-    if ( (pdev = (phys_dev_t *)dev_id) == NULL )
-    {
-        printk("spurious interrupt, no proper device id, %d\n", irq);
-        return;
-    }
-    
-    /* XXX KAF: introduced race here? */
-    set_bit(ST_IRQ_DELIVERED, &pdev->state);
-    send_guest_pirq(pdev->owner, irq);
-}
-
-/* this is called instead of the PICs original end handler. 
- * the real end handler is only called once the guest signalled the handling
- * of the event. */
-static void end_virt_irq (unsigned int i)
-{
-    /* nothing */
-}
-
-/*
- * a guest request an IRQ from a device to be routed to it
- * - shared interrupts are not allowed for now
- * - we change the hw_irq handler to something else
- */
-static long pirq_request(int irq)
-{
-    int err;
-    phys_dev_t *pdev = NULL, *t;
-    hw_irq_controller *new, *orig;
-    struct list_head *tmp;
-
-    printk("request irq %d\n", irq);
-
-    /* find pdev */
-
-    list_for_each(tmp, &current->pcidev_list)
-    {
-        t = list_entry(tmp,  phys_dev_t, node);
-        if ( t->dev->irq == irq )
-        {
-            pdev = t;
-            break;
-        }
-    }
-
-    if ( pdev == NULL )
-    {
-        printk("no device matching IRQ %d\n", irq);
-        return -EINVAL;
-    }
-
-    if ( irq >= MAX_IRQS )
-    {
-        printk("requested IRQ to big %d\n", irq);
-        return -EINVAL;
-    }
-
-    if ( irqs[irq] != NULL )
-    {
-        printk ("irq already in use %d\n", irq);
-        return -EPERM;
-    }
-
-    /* allocate a hw_irq controller and copy the original */
-    if ( !(new  = kmalloc(sizeof(hw_irq_controller), GFP_KERNEL)) )
-    {
-        printf("error allocating new irq controller\n");
-        return -ENOMEM;
-    }
-    orig = irq_desc[irq].handler;
-    new->typename = orig->typename;
-    new->startup = orig->startup;
-    new->shutdown = orig->shutdown;
-    new->enable = orig->enable;
-    new->disable = orig->disable;
-    new->ack = orig->ack;
-    new->end = orig->end;
-    new->set_affinity = orig->set_affinity;
-
-    /* swap the end routine */
-    new->end = end_virt_irq;
-
-    /* change the irq controllers */
-    pdev->orig_handler = orig;
-    pdev->new_handler  = new;
-    irq_desc[irq].handler = new;
-    irqs[irq] = pdev;
-    
-    printk ("setup handler %d\n", irq);
-
-    /* request the IRQ. this is not shared and we use a slow handler! */
-    err = request_irq(irq, phys_dev_interrupt, SA_INTERRUPT,
-                      "foo", (void *)pdev);
-    if ( err )
-    {
-        printk("error requesting irq\n");
-        /* restore original */
-        irq_desc[irq].handler = pdev->orig_handler;
-        /* free memory */
-        kfree(new);
-        return err;
-    }
-
-    printk ("done\n");
-
-    return 0;
-}
-
-long pirq_free(int irq)
-{
-    phys_dev_t *pdev;
-
-    if ( irq >= MAX_IRQS )
-    {
-        printk("requested IRQ to big %d\n", irq);
-        return -EINVAL;
-    }
-
-    if ( irqs[irq] == NULL )
-    {
-        printk ("irq not used %d\n", irq);
-        return -EINVAL;
-    }
-
-    pdev = irqs[irq];
-
-    /* shutdown IRQ */
-    free_irq(irq, (void *)pdev);
-
-    /* restore irq controller  */
-    irq_desc[irq].handler = pdev->orig_handler;
-
-    /* clean up */
-    pdev->orig_handler = NULL;
-    irqs[irq] = NULL;
-    kfree(pdev->new_handler);
-    pdev->new_handler = NULL;
-
-    printk("freed irq %d", irq);
-    return 0;
-}
 
 static long pci_unmask_irq(void)
 {
-#if 0
-    clear_bit(ST_IRQ_DELIVERED, &pdev->state);
-    pdev->orig_handler->end(irq);
-#endif
     return 0;
 }
 
index d0fe21acb09792d275899da859f0037947432834..2eeb70cf89297bf46dfe4085859ece7cdb3848d1 100644 (file)
@@ -227,8 +227,8 @@ long read_console_ring(unsigned long str, unsigned int count, unsigned cmd)
 static char serial_rx_ring[SERIAL_RX_SIZE];
 static unsigned int serial_rx_cons, serial_rx_prod;
 
-/* CTRL-a switches input direction between Xen and DOM0. */
-#define CTRL_A 0x01
+/* CTRL-g switches input direction between Xen and DOM0. */
+#define CTRL_G 0x07
 static int xen_rx = 1; /* FALSE => serial input passed to domain 0. */
 
 static void switch_serial_input(void)
@@ -236,7 +236,7 @@ static void switch_serial_input(void)
     static char *input_str[2] = { "DOM0", "Xen" };
     xen_rx = !xen_rx;
     printk("*** Serial input -> %s "
-           "(type 'CTRL-a' three times to switch input to %s).\n",
+           "(type 'CTRL-g' three times to switch input to %s).\n",
            input_str[xen_rx], input_str[!xen_rx]);
 }
 
@@ -264,22 +264,22 @@ static void __serial_rx(unsigned char c, struct pt_regs *regs)
 
 static void serial_rx(unsigned char c, struct pt_regs *regs)
 {
-    static int ctrl_a_count = 0;
+    static int ctrl_g_count = 0;
 
-    if ( c == CTRL_A )
+    if ( c == CTRL_G )
     {
-        /* We eat CTRL-a in groups of three to switch console input. */
-        if ( ++ctrl_a_count == 3 )
+        /* We eat CTRL-g in groups of three to switch console input. */
+        if ( ++ctrl_g_count == 3 )
         {
             switch_serial_input();
-            ctrl_a_count = 0;
+            ctrl_g_count = 0;
         }
     }
     else
     {
-        /* Flush any pending CTRL-a's. They weren't for us. */
-        for ( ; ctrl_a_count != 0; ctrl_a_count-- )
-            __serial_rx(CTRL_A, regs);
+        /* Flush any pending CTRL-b's. They weren't for us. */
+        for ( ; ctrl_g_count != 0; ctrl_g_count-- )
+            __serial_rx(CTRL_G, regs);
         /* Finally process the just-received character. */
         __serial_rx(c, regs);
     }
index cf1094bf0f29ba52dc3d07a905c9fb85a3962e7e..2c7c67a0dacda7d3200e337ba2b86f60e17ea716 100644 (file)
@@ -192,10 +192,10 @@ extern unsigned long prof_shift;
 
 #include <xen/irq.h>
 
-#ifdef CONFIG_SMP /*more of this file should probably be ifdefed SMP */
+#if defined(CONFIG_X86_IO_APIC)
 static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {
-       if (IO_APIC_IRQ(i))
-               send_IPI_self(IO_APIC_VECTOR(i));
+        if (IO_APIC_IRQ(i))
+                send_IPI_self(IO_APIC_VECTOR(i));
 }
 #else
 static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
index 74e0495555d773445ecf647ae6c1e26e964d9949..bbb83c2d9561df6bc53ec1b54bcb7318517b58dd 100644 (file)
@@ -124,10 +124,10 @@ extern unsigned long prof_shift;
 
 #include <xen/irq.h>
 
-#ifdef CONFIG_SMP /*more of this file should probably be ifdefed SMP */
+#if defined(CONFIG_X86_IO_APIC)
 static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {
-       if (IO_APIC_IRQ(i))
-               send_IPI_self(IO_APIC_VECTOR(i));
+        if (IO_APIC_IRQ(i))
+                send_IPI_self(IO_APIC_VECTOR(i));
 }
 #else
 static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
index f9f2762d9bb154ff456cdc68267297e3ec7cc91e..a55e70269fa8712a2fb5de1e45645079f008358f 100644 (file)
@@ -16,7 +16,7 @@ typedef void irqreturn_t;
 #define IRQ_NONE
 #define IRQ_HANDLED
 #define IRQ_RETVAL(x)
-                                                                                
+
 struct irqaction {
        void (*handler)(int, void *, struct pt_regs *);
        unsigned long flags;
@@ -26,7 +26,6 @@ struct irqaction {
        struct irqaction *next;
 };
 
-
 enum {
        TIMER_BH = 0,
        SCSI_BH
index f4d81bec793729a173b7d81ee297527d1b7133d0..169c4170cb1918b6dcb19c66379db61a856e3483 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __irq_h
-#define __irq_h
+#ifndef __XEN_IRQ_H__
+#define __XEN_IRQ_H__
 
 #include <xen/config.h>
 #include <xen/spinlock.h>
 #define IRQ_REPLAY     8       /* IRQ has been replayed but not acked yet */
 #define IRQ_AUTODETECT 16      /* IRQ is being autodetected */
 #define IRQ_WAITING    32      /* IRQ not yet seen - for autodetection */
-#define IRQ_LEVEL      64      /* IRQ level triggered */
-#define IRQ_MASKED     128     /* IRQ masked - shouldn't be seen again */
-#define IRQ_PER_CPU    256     /* IRQ is per CPU */
+#define IRQ_GUEST       64      /* IRQ is handled by guest OS(es) */
 
 /*
  * Interrupt controller descriptor. This is all we need
  * to describe about the low-level hardware. 
  */
 struct hw_interrupt_type {
-       const char * typename;
-       unsigned int (*startup)(unsigned int irq);
-       void (*shutdown)(unsigned int irq);
-       void (*enable)(unsigned int irq);
-       void (*disable)(unsigned int irq);
-       void (*ack)(unsigned int irq);
-       void (*end)(unsigned int irq);
-       void (*set_affinity)(unsigned int irq, unsigned long mask);
+    const char *typename;
+    unsigned int (*startup)(unsigned int irq);
+    void (*shutdown)(unsigned int irq);
+    void (*enable)(unsigned int irq);
+    void (*disable)(unsigned int irq);
+    void (*ack)(unsigned int irq);
+    void (*end)(unsigned int irq);
+    void (*set_affinity)(unsigned int irq, unsigned long mask);
 };
 
-typedef struct hw_interrupt_type  hw_irq_controller;
+typedef struct hw_interrupt_type hw_irq_controller;
 
 #include <asm/irq.h>
 
@@ -45,19 +43,22 @@ typedef struct hw_interrupt_type  hw_irq_controller;
  * Pad this out to 32 bytes for cache and indexing reasons.
  */
 typedef struct {
-       unsigned int status;            /* IRQ status */
-       hw_irq_controller *handler;
-       struct irqaction *action;       /* IRQ action list */
-       unsigned int depth;             /* nested irq disables */
-       spinlock_t lock;
+    unsigned int status;               /* IRQ status */
+    hw_irq_controller *handler;
+    struct irqaction *action;  /* IRQ action list */
+    unsigned int depth;                /* nested irq disables */
+    spinlock_t lock;
 } ____cacheline_aligned irq_desc_t;
 
-extern irq_desc_t irq_desc [NR_IRQS];
+extern irq_desc_t irq_desc[NR_IRQS];
 
-extern int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
-extern int setup_irq(unsigned int , struct irqaction * );
+extern int setup_irq(unsigned int, struct irqaction *);
 
-extern hw_irq_controller no_irq_type;  /* needed in every arch ? */
+extern hw_irq_controller no_irq_type;
 extern void no_action(int cpl, void *dev_id, struct pt_regs *regs);
 
-#endif /* __asm_h */
+struct task_struct;
+extern int pirq_guest_bind(struct task_struct *p, int irq);
+extern int pirq_guest_unbind(struct task_struct *p, int irq);
+
+#endif /* __XEN_IRQ_H__ */